#ifndef _SIMULATIONUNIT_H_
#define _SIMULATIONUNIT_H_

#include "fmi2Functions.h"

#include <windows.h>


/**
 * @class SimulationUnit
 * @brief 仿真单元类，通过读取 FMU 动态库生成，用于在仿真环境中通过 FMI 接口以完成 FMU 的仿真流程。
 */
class SimulationUnit
{

public:

    /**
     * @brief 构造函数，将加载 FMU 动态库文件并尝试解析其中的 FMI 接口。
     * @param szFmuFileName FMU 文件名
     * @param instanceName 仿真实例名
     * @param resourcePath 资源目录路径
     */
    SimulationUnit(LPCTSTR szFmuFileName, fmi2String instanceName, fmi2String resourcePath = nullptr);

    /**
     * @brief 析构函数，将释放所有未释放的资源。
     */
    ~SimulationUnit();

    /**
     * @brief 判断仿真单元是否加载成功。
     */
    bool isLoaded() const { return (m_hModule != nullptr); }

    /**
     * @brief 返回系统错误代码。
     */
    DWORD errorCode() const { return m_errorCode; }

    /**
     * @brief FMI：返回类型平台字符串。
     */
    const char *getTypesPlatform() const;

    /**
     * @brief FMI：获取 FMI 版本号字符串。
     */
    const char *getVersion() const;

    /**
     * @brief FMI：设置本次仿真的基本参数。
     * @param timeStart 仿真起始时间
     * @param timeStop 仿真终止时间
     */
    fmi2Status setupExperiment(fmi2Real timeStart, fmi2Real timeStop);

    /**
     * @brief FMI：读取整数变量值。
     * @param vr 变量引用列表
     * @param nvr 读取的变量数量
     * @param value 用于存放读取到的各变量值
     */
    fmi2Status getInteger(const fmi2ValueReference vr[], size_t nvr, fmi2Integer value[]);

    /**
     * @brief FMI：写入整数变量值。
     * @param vr 变量引用列表
     * @param nvr 写入的变量数量
     * @param value 准备写入到各变量的值
     */
    fmi2Status setInteger(const fmi2ValueReference vr[], size_t nvr, const fmi2Integer value[]);

    /**
     * @brief FMI (CoSim)：推进仿真步骤。
     * @param timeCurrent 当前仿真时间点
     * @param timeInterval 仿真时间步长
     */
    fmi2Status doStep(fmi2Real timeCurrent, fmi2Real timeInterval);


private:

    /**
     * @brief FMI：实例化仿真单元。
     * @param instanceName 仿真实例名
     * @param resourcePath 资源目录路径
     */
    bool instantiate(fmi2String instanceName, fmi2String resourcePath = nullptr);

    /**
     * @brief FMI：释放仿真单元实例。
     */
    void freeInstance();

    /**
     * @brief 动态库句柄。
     */
    HMODULE m_hModule = nullptr;

    /**
     * @brief 加载动态库时发生错误的代码。
     */
    DWORD m_errorCode = 0;

    /**
     * @brief 仿真单元实例。
     */
    fmi2Component m_pUnitInstance = nullptr;
    
    fmi2GetTypesPlatformTYPE *m_fpGetTypesPlatform = nullptr;
    fmi2GetVersionTYPE *m_fpGetVersion = nullptr;

    fmi2SetupExperimentTYPE *m_fpSetupExperiment = nullptr;

    fmi2GetIntegerTYPE *m_fpGetInteger = nullptr;
    fmi2SetIntegerTYPE *m_fpSetInteger = nullptr;

    fmi2InstantiateTYPE *m_fpInstantiate = nullptr;
    fmi2FreeInstanceTYPE *m_fpFreeInstance = nullptr;
    fmi2DoStepTYPE *m_fpDoStep = nullptr;


};


#endif